package cn.angis.system.controller;

import cn.angis.common.annotation.SLog;
import cn.angis.common.constant.Constant;
import cn.angis.common.model.PageModel;
import cn.angis.common.model.PageResult;
import cn.angis.common.model.R;
import cn.angis.db.controller.BaseController;
import cn.angis.system.dto.input.ResourceInput;
import cn.angis.system.dto.output.ResourceOutput;
import cn.angis.system.dto.output.RouterOutput;
import cn.angis.system.dtomapper.ResourceStruct;
import cn.angis.system.model.Resource;
import cn.angis.system.service.ResourceService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Post;
import org.noear.solon.validation.annotation.NotBlank;
import org.noear.solon.validation.annotation.NotEmpty;
import org.noear.solon.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.List;

/**
* 资源表前端控制器
* @author angis.cn
* @Date 2023-01-05
*/
@SLog("菜单管理")
@Mapping("/system/resource/")
@Controller
public class ResourceController extends BaseController<ResourceService, Resource> {

    /**
    * 分页查询
    * @param resourceInput
    * @param pageModel
    * @return R<PageResult<ResourceOutput>>
    * @Date 2023-01-05
    */
    @Get
    @SLog
    @Mapping("page")
    public R<PageResult<ResourceOutput>> page(ResourceInput resourceInput, PageModel pageModel) {
        Resource resource = ResourceStruct.INSTANCE.toResource(resourceInput);
        PageResult<Resource> pageResult = pageListByEntity(resource, pageModel);
        List<ResourceOutput> resourceOutputList = ResourceStruct.INSTANCE.toOutputList(pageResult.getRecords());
        return success(toPageDTO(pageResult, resourceOutputList));
    }

    /**
     * 获取当前用户路由
     * @return: R<List<RouterOutput>>
     * @throws:
     * @Date: 2023/1/9
     */
    @Get
    @Mapping("getRouterList")
    public R<List<RouterOutput>> getResourceList() {
        List<Resource> resourcesList = baseService.listByUserId();
        return success(generateRouter(resourcesList));
    }

    /**
     * 获取菜单树列表
     * @return: R<List<ResourceOutput>>
     * @throws: 
     * @Date: 2023/1/10     
     */
    @Get
    @SLog
    @Mapping("getResourceTreeList")
    public R<List<ResourceOutput>> getResourceTreeList() {
        List<Resource> resourceTreeList = baseService.getResourceTreeList();
        List<ResourceOutput> resourceOutputList = ResourceStruct.INSTANCE.toOutputList(resourceTreeList);
        return success(resourceOutputList);
    }

    /**
     * 获取菜单列表数据
     * @return: R<List<ResourceOutput>>
     * @throws: 
     * @Date: 2023/1/10     
     */
    @Get
    @Mapping("getMenuList")
    public R<List<ResourceOutput>> getMenuList() {
        List<Resource> resourceTreeList = baseService.getMenuList();
        List<ResourceOutput> resourceOutputList = ResourceStruct.INSTANCE.toOutputList(resourceTreeList);
        return success(resourceOutputList);
    }

    /**
     * 根据角色id获取资源tree列表数据
     * @param roleId
     * @return: R<List<String>>
     * @throws: 
     * @Date: 2023/1/10     
     */
    @Get
    @Mapping("getResourceIdListByRoleId")
    public R<List<String>> getResourceIdListByRoleId(@NotBlank(message = "角色id不能为空") String roleId) {
        return success(baseService.getResourceIdListByRoleId(roleId));
    }

    /**
    * 保存
    * @param resourceInput
    * @return R<Boolean>
    * @Date 2023-01-05
    */
    @Post
    @SLog
    @Mapping("save")
    public R<Boolean> save(@Validated ResourceInput resourceInput) {
        Resource resource = ResourceStruct.INSTANCE.toResource(resourceInput);
        return super.save(resource);
    }

    /**
    * 修改
    * @param resourceInput
    * @return R<Boolean>
    * @Date 2023-01-05
    */
    @Post
    @SLog
    @Mapping("update")
    public R<Boolean> update(@Validated ResourceInput resourceInput) {
        Resource resource = ResourceStruct.INSTANCE.toResource(resourceInput);
        return super.update(resource);
    }

    /**
    * 删除
    * @param id
    * @return R<Boolean>
    * @Date 2023-01-05
    */
    @Post
    @SLog
    @Mapping("delete")
    public R<Boolean> delete(@NotBlank String id) {
        return super.delete(id);
    }

    /**
    * 批量删除
    * @param ids
    * @return R<Boolean>
    * @Date 2023-01-05
    */
    @Post
    @SLog
    @Mapping("deleteBatch")
    public R<Boolean> deleteBatch(@NotEmpty List<String> ids) {
        return super.deleteBatch(Resource.class, ids);
    }

    private List<RouterOutput> generateRouter(List<Resource> resourcesList) {
        List<RouterOutput> routerListOutput = new ArrayList<>();
        resourcesList.forEach(resources -> {
            final List<Resource> children = resources.getChildren();
            RouterOutput routerOutput = new RouterOutput();
            routerOutput.setId(resources.getId());
            routerOutput.setParentId(resources.getParentId());
            routerOutput.setName(resources.getComponentName());
            routerOutput.setPath(resources.getRoutePath());
            if (!Constant.DISABLE.equals(resources.getMenuExtFlag())) {
                // 一级菜单
                if (Constant.COMMON_PARENT_ID.equals(resources.getParentId())) {
                    routerOutput.setComponent(StrUtil.isBlank(resources.getVuePath()) ? Constant.ROUTER_LAYOUT : resources.getVuePath());
                    // 如果不是一级菜单，并且菜单类型为目录，则代表是多级菜单
                } else if (Constant.DISABLE.equals(resources.getType())) {
                    routerOutput.setComponent(StrUtil.isBlank(resources.getVuePath()) ? Constant.ROUTER_PARENT_VIEW : resources.getVuePath());
                } else if (StrUtil.isNotBlank(resources.getVuePath())) {
                    routerOutput.setComponent(resources.getVuePath());
                }
            }
            // 设置元信息
            final RouterOutput.MetaOutput metaOutput = new RouterOutput.MetaOutput();
            metaOutput.setIcon(resources.getMenuIcon());
            metaOutput.setTitle(resources.getTitle());
            metaOutput.setIsHide(Constant.DISABLE.equals(resources.getMenuHiddenFlag()));
            metaOutput.setIsKeepAlive(Constant.DISABLE.equals(resources.getMenuCacheFlag()));
            routerOutput.setMeta(metaOutput);
            if (CollUtil.isNotEmpty(children)) {
                routerOutput.setRedirect(null);
                routerOutput.setChildren(generateRouter(children));
            } else if (Constant.COMMON_PARENT_ID.equals(resources.getParentId()) && StrUtil.isNotBlank(resources.getVuePath())) {
            } else if (Constant.COMMON_PARENT_ID.equals(resources.getParentId())) {
                RouterOutput routerOutputChild = new RouterOutput();
                routerOutputChild.setMeta(routerOutput.getMeta());
                // 不是外链
                if (!Constant.DISABLE.equals(resources.getMenuExtFlag())) {
                    routerOutputChild.setName(resources.getComponentName());
                    routerOutputChild.setComponent(resources.getVuePath());
                }
                routerOutputChild.setPath(resources.getRoutePath());
                routerOutput.setName(resources.getComponentName());
                routerOutput.setComponent(Constant.ROUTER_LAYOUT);
                List<RouterOutput> listOutputDTOS = new ArrayList<>();
                listOutputDTOS.add(routerOutputChild);
                routerOutput.setChildren(listOutputDTOS);
            }
            routerListOutput.add(routerOutput);
        });
        return routerListOutput;
    }
}
